<template>
  <div class="canvas-container">
    <canvas 
      ref="canvas"
      class="game-canvas"
      @mousedown="startDrawing"
      @mousemove="handleMouseMove"
      @mouseup="stopDrawing"
      @mouseleave="stopDrawing"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
    ></canvas>
    
    <!-- 游戏状态提示 -->
    <div v-if="gameStatus === 'waiting'" class="game-status-overlay waiting">
      <div class="status-content">
        <h3>等待游戏开始</h3>
        <p>房主可以点击"开始游戏"按钮开始游戏</p>
        <div class="player-ready-status">
          <div v-for="player in players" :key="player.id" class="player-status">
            <span class="player-name">{{ player.name }}</span>
            <span :class="['ready-indicator', player.isReady ? 'ready' : 'not-ready']">
              {{ player.isReady ? '✅ 已准备' : '⏳ 未准备' }}
            </span>
          </div>
        </div>
      </div>
    </div>
    
    <!-- playing 状态不再覆盖画布，避免遮挡与重复提示 -->
    
    <!-- 游戏结束提示 -->
    <div v-if="gameStatus === 'finished'" class="game-status-overlay finished">
      <div class="status-content">
        <h3>游戏结束</h3>
        <div class="final-ranking">
          <h4>最终排名:</h4>
          <div v-for="(player, index) in sortedPlayers" :key="player.id" class="ranking-item">
            <span class="rank">{{ index + 1 }}</span>
            <span class="player-name">{{ player.name }}</span>
            <span class="score">{{ player.area }} 像素</span>
          </div>
        </div>
        <button @click="resetGame" class="reset-btn">重新开始</button>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, watch, nextTick, computed } from 'vue'
import { useGameStore } from '@/stores/game'
import { useSocketStore } from '@/stores/socket'
import { useUserStore } from '@/stores/user'

export default {
  name: 'GameCanvas',
  props: {
    selectedColor: { type: String, required: true },
    brushSize: { type: Number, required: true },
    gameStatus: { type: String, required: true },
    canvasData: { type: Object, required: true },
    canvasDataVersion: { type: Number, default: 0 }
  },
  emits: ['pixel-added', 'canvas-initialized', 'canvas-stats-updated'],
  setup(props, { emit }) {
    const canvas = ref(null)
    const isDrawing = ref(false)
    let ctx = null
    let lastX = 0
    let lastY = 0
    const pixelQueue = []
    let isProcessingPixels = false
    let isDrawingActive = false
    // 有效游戏状态：同时兼容父级传入与全局store，避免状态不同步导致无法绘制
    const isGameActive = computed(() => {
      try {
        const isPlaying = (props.gameStatus === 'playing' || gameStore.gameStatus === 'playing')
        const isFinished = (props.gameStatus === 'finished' || gameStore.gameStatus === 'finished')
        return isPlaying && !isFinished
      } catch (_) {
        return false
      }
    })
    const gameStore = useGameStore()
    const socketStore = useSocketStore()
    const userStore = useUserStore()
    
    // 计算属性
    const players = computed(() => gameStore.players)
    const currentPlayer = computed(() => gameStore.currentPlayer)
    const sortedPlayers = computed(() => gameStore.sortedPlayers)
    
    // 格式化时间显示
    const formatTime = (seconds) => {
      const mins = Math.floor(seconds / 60)
      const secs = seconds % 60
      return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
    }
    
    // 重置游戏
    const resetGame = () => {
      gameStore.resetGame()
    }
    
    // 获取鼠标/触摸位置
    const getPosition = (e) => {
      const rect = canvas.value.getBoundingClientRect()
      const clientX = e.clientX || (e.touches && e.touches[0] ? e.touches[0].clientX : 0)
      const clientY = e.clientY || (e.touches && e.touches[0] ? e.touches[0].clientY : 0)
      
      return {
        x: Math.floor(clientX - rect.left),
        y: Math.floor(clientY - rect.top)
      }
    }
    
    // 处理像素队列
    const processPixelQueue = () => {
      if (isProcessingPixels || pixelQueue.length === 0) return
      
      isProcessingPixels = true
      const pixels = [...pixelQueue]
      pixelQueue.length = 0 // 清空队列
      
      console.log(`📤 批量上报 ${pixels.length} 个像素`)
      
      // 批量上报像素
      requestAnimationFrame(() => {
        pixels.forEach(pixel => {
          emit('pixel-added', pixel)
        })
        
        isProcessingPixels = false
        
        // 如果队列中还有像素，继续处理
        if (pixelQueue.length > 0) {
          requestAnimationFrame(processPixelQueue)
        }
      })
    }
    
    // 添加像素到队列
    const addPixelToQueue = (pixel) => {
      pixelQueue.push(pixel)
      if (pixelQueue.length >= 40) {
        if (!isProcessingPixels) processPixelQueue()
      } else {
        setTimeout(() => {
          if (!isProcessingPixels) processPixelQueue()
        }, 75)
      }
    }
    
    // 检查像素是否已存在（避免重复统计）
    const drawPixel = (x, y) => {
      if (x < 0 || x >= canvas.value.width || y < 0 || y >= canvas.value.height) return false
      
      // 创建像素数据但不直接修改props
      const pixelData = { x, y, color: props.selectedColor, brushSize: props.brushSize }
      addPixelToQueue(pixelData)
      
      // 🔧 修复：同步到后端（实时广播给其他玩家）
      try {
        const roomId = String(gameStore.currentRoomId || '')
        console.log('🎨 准备发送绘画动作...')
        console.log('🎨 房间ID:', roomId)
        console.log('🎨 Socket连接状态:', socketStore.isConnected)
        console.log('🎨 当前用户ID:', userStore?.user?.id || userStore?.userId)
        
        if (socketStore && socketStore.isConnected && roomId) {
          const currentUserId = gameStore.currentPlayer?.id || userStore?.user?.id || userStore?.userId
          const payload = { 
            roomId, 
            x: Math.floor(x), 
            y: Math.floor(y), 
            color: props.selectedColor, 
            brushSize: props.brushSize, 
            tool: 'brush',
            playerId: currentUserId,
            playerName: gameStore.currentPlayer?.name || userStore?.user?.userName || 'Unknown'
          }
          
          console.log('🎨 发送绘画动作payload:', payload)
          socketStore.paintAction(payload)
          console.log('✅ 绘画动作已发送')
          
          // 🔧 立即更新本地画布，提供即时反馈
          gameStore.updateCanvasPixel({
            x: Math.floor(x),
            y: Math.floor(y),
            color: props.selectedColor,
            playerName: gameStore.currentPlayer?.name || userStore?.user?.userName || 'Unknown',
            playerId: currentUserId,
            brushSize: props.brushSize,
            timestamp: Date.now()
          })
        } else {
          console.warn('⚠️ 无法发送绘画动作:', {
            hasSocketStore: !!socketStore,
            isConnected: socketStore?.isConnected,
            roomId: roomId
          })
        }
      } catch (error) {
        console.error('发送绘画动作失败:', error)
      }
      return true
    }
    
    // 🔧 彻底修复：开始绘制，禁用面积统计
    const startDrawing = (e) => {
      if (!isGameActive.value) return
      
      e.preventDefault()
      isDrawing.value = true
      isDrawingActive = true // 🔧 标记绘制开始
      const pos = getPosition(e)
      lastX = pos.x
      lastY = pos.y
      
      // 🔧 修复：确保绘制路径正确初始化
      if (ctx) {
        // 设置绘制样式
        ctx.strokeStyle = props.selectedColor
        ctx.lineWidth = Math.max(1, props.brushSize)
        ctx.lineCap = 'round'
        ctx.lineJoin = 'round'
        
        // 开始新的绘制路径
        ctx.beginPath()
        ctx.moveTo(lastX, lastY)
        
        // 立即绘制第一个点
        ctx.fillStyle = props.selectedColor
        ctx.beginPath()
        ctx.arc(lastX, lastY, Math.max(1, props.brushSize) / 2, 0, Math.PI * 2)
        ctx.fill()
        
        // 重新开始路径用于线条绘制
        ctx.beginPath()
        ctx.moveTo(lastX, lastY)
        
        // 🔧 立即处理第一个像素的统计
        drawPixel(lastX, lastY)
      }
    }
    
    // 🔧 彻底修复：绘制过程，完全禁用统计，确保画笔流畅
    const draw = (e) => {
      if (!isDrawing.value || !ctx || !isGameActive.value) return
      
      e.preventDefault()
      
      const pos = getPosition(e)
      const x = pos.x
      const y = pos.y
      
      // 1. 通过连续路径描边，不在每个采样点额外绘制圆点
 
      // 2. 绘制连接线（确保连续性）
      if (lastX !== 0 || lastY !== 0) {
        ctx.lineWidth = Math.max(1, props.brushSize)
        ctx.strokeStyle = props.selectedColor
        ctx.lineTo(x, y)
        ctx.stroke()
      }
 
      // 3. 更新位置
      lastX = x
      lastY = y
 
      // 🔧 4. 实时收集像素，触发统计更新
      drawPixel(x, y)
    }
    
    // 处理快速滑动时的连续性：插值改为路径描边，避免画圆导致颗粒感
    const handleMouseMove = (e) => {
      if (!isDrawing.value || !ctx || !isGameActive.value) return
      
      e.preventDefault()
      
      const pos = getPosition(e)
      const x = pos.x
      const y = pos.y
      
      // 计算与上一个点的距离
      const distance = Math.sqrt((x - lastX) ** 2 + (y - lastY) ** 2)
      
      // 如果距离太大，插值填充中间点
      if (distance > 5) {
        const steps = Math.ceil(distance / 3)
        for (let i = 1; i <= steps; i++) {
          const t = i / steps
          const interpX = lastX + (x - lastX) * t
          const interpY = lastY + (y - lastY) * t
          
          // 使用路径连接插值点，避免圆点导致的颗粒感
          ctx.lineWidth = Math.max(1, props.brushSize)
          ctx.strokeStyle = props.selectedColor
          ctx.lineTo(interpX, interpY)
          ctx.stroke()
          // 收集插值点统计
          drawPixel(interpX, interpY)
          lastX = interpX
          lastY = interpY
        }
      }
      
      // 正常绘制当前点
      draw(e)
    }
    
    // 🔧 智能统计：停止绘制，立即处理待处理的统计
    const stopDrawing = () => {
      if (isDrawing.value && ctx) {
        // 确保最后的路径被绘制
        ctx.stroke()
      }
      
      isDrawing.value = false
      isDrawingActive = false // 🔧 标记绘制结束
      lastX = 0
      lastY = 0
      
      // 🔧 智能统计：绘制结束后立即处理所有待处理的像素
      if (pixelQueue.length > 0) {
        // 立即处理队列
        setTimeout(() => {
          if (!isProcessingPixels) {
            processPixelQueue()
          }
        }, 50) // 50ms后处理，确保绘制完全结束
      }
    }
    
    // 触摸事件处理
    const handleTouchStart = (e) => {
      e.preventDefault()
      startDrawing(e)
    }
    
    const handleTouchMove = (e) => {
      e.preventDefault()
      draw(e)
    }
    
    const handleTouchEnd = (e) => {
      e.preventDefault()
      stopDrawing()
    }
    
    // 初始化画布
    const initCanvas = () => {
      if (!canvas.value) return
      
      ctx = canvas.value.getContext('2d', { 
        alpha: false,
        willReadFrequently: false,
        desynchronized: true // 启用异步绘制
      })
      
      // 设置画布尺寸
      canvas.value.width = canvas.value.offsetWidth
      canvas.value.height = canvas.value.offsetHeight
      
      // 优化绘制性能
      ctx.imageSmoothingEnabled = false
      ctx.imageSmoothingQuality = 'high'
      
      // 设置背景
      ctx.fillStyle = '#FFFFFF'
      ctx.fillRect(0, 0, canvas.value.width, canvas.value.height)
      
      emit('canvas-initialized', { 
        width: canvas.value.width, 
        height: canvas.value.height 
      })
    }
    
    // 重绘画布 - 优化版本，减少延迟
    const redrawCanvas = () => {
      console.log('🎨 redrawCanvas 被调用')
      if (!canvas.value || !ctx.value) {
        console.log('❌ Canvas 或 Context 不存在，跳过重绘')
        return
      }
      
      console.log('✅ 开始重绘画布，当前 pixels 数量:', Object.keys(props.canvasData.pixels || {}).length)
      
      // 清空画布
      ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)
      
      // 使用离屏canvas优化渲染
      const offscreenCanvas = document.createElement('canvas')
      offscreenCanvas.width = canvas.value.width
      offscreenCanvas.height = canvas.value.height
      const offscreenCtx = offscreenCanvas.getContext('2d')
      
      // 批量绘制所有像素
      if (props.canvasData.pixels) {
        Object.values(props.canvasData.pixels).forEach(pixel => {
          if (pixel && pixel.x !== undefined && pixel.y !== undefined) {
            offscreenCtx.fillStyle = pixel.color
            offscreenCtx.fillRect(pixel.x, pixel.y, 1, 1)
          }
        })
      }
      
      // 一次性绘制到主画布
      ctx.value.drawImage(offscreenCanvas, 0, 0)
    }
    
    // 清空画布
    const clearCanvas = () => {
      if (!ctx || !canvas.value) return
      ctx.clearRect(0, 0, canvas.value.width, canvas.value.height)
      ctx.fillStyle = '#FFFFFF'
      ctx.fillRect(0, 0, canvas.value.width, canvas.value.height)
      
      // 清空离屏Canvas
      // if (offscreenCanvas && offscreenCtx) { // Removed as per edit hint
      //   offscreenCtx.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height) // Removed as per edit hint
      //   offscreenCtx.fillStyle = '#FFFFFF' // Removed as per edit hint
      //   offscreenCtx.fillRect(0, 0, offscreenCanvas.width, offscreenCanvas.height) // Removed as per edit hint
      // } // Removed as per edit hint
    }
    
    // 监听轻量版本号变化 - 节流重绘，绘制时跳过
    let redrawScheduled = false
    watch(() => props.canvasDataVersion, (newVersion, oldVersion) => {
      console.log('📈 Canvas 版本号变化:', oldVersion, '->', newVersion)
      // 正在手绘时不触发重绘，避免与实时绘制竞争
      if (isDrawing.value || isDrawingActive) {
        console.log('⏸️ 正在手绘中，跳过重绘')
        return
      }
      if (redrawScheduled) {
        console.log('⏸️ 重绘已计划中，跳过')
        return
      }
      redrawScheduled = true
      console.log('🔄 计划重绘，延迟 100ms')
      setTimeout(() => {
        try { 
          redrawCanvas() 
          console.log('✅ 重绘完成')
        } finally { 
          redrawScheduled = false 
          console.log('🔄 重绘计划状态已重置')
        }
      }, 100) // 从300ms减少到100ms，大幅提升响应速度
    })
    
    // 监听笔刷大小变化 - 动态更新，不重绘
    watch(() => props.brushSize, () => {
      // 笔刷大小变化时，只更新绘制上下文，不重绘画布
      // 这样可以在原来的基础上继续绘制，而不是重新开始
      if (ctx && isDrawing.value) {
        // 如果正在绘制，动态更新笔刷大小
        ctx.lineWidth = Math.max(1, props.brushSize)
      }
    })
    
    // 监听颜色变化，动态更新，不重绘
    watch(() => props.selectedColor, () => {
      // 颜色变化时，只更新绘制上下文，不重绘画布
      // 这样可以在原来的基础上继续绘制，而不是重新开始
      if (ctx && isDrawing.value) {
        // 如果正在绘制，动态更新颜色
        ctx.strokeStyle = props.selectedColor
      }
    })
    
    onMounted(() => {
      nextTick(() => {
        initCanvas()
        // createOffscreenCanvas() // Removed as per edit hint
      })
    })
    
    return { 
      canvas, 
      startDrawing, 
      draw, 
      handleMouseMove,
      stopDrawing, 
      redrawCanvas, 
      clearCanvas,
      handleTouchStart,
      handleTouchMove,
      handleTouchEnd,
      resetGame,
      players,
      currentPlayer,
      sortedPlayers,
      formatTime,
      gameTime: gameStore.gameTime
    }
  }
}
</script>

<style scoped>
.canvas-container { 
  flex: 1; 
  position: relative; 
  background-color: white; 
  display: flex; 
  align-items: stretch; 
  justify-content: stretch; 
  overflow: hidden;
}

.game-canvas { 
  border: none; 
  border-radius: 0; 
  cursor: crosshair; 
  width: 100%; 
  height: 100%; 
  object-fit: cover;
  touch-action: none; /* 禁用默认触摸行为 */
  image-rendering: -webkit-optimize-contrast; /* 优化图像渲染 */
  image-rendering: crisp-edges;
}

.game-tip { 
  position: absolute; 
  top: 20px; 
  left: 20px; 
  background-color: rgba(255, 255, 255, 0.95); 
  border: 1px solid #e5e7eb; 
  border-radius: 8px; 
  padding: 12px 16px; 
  display: flex; 
  align-items: center; 
  gap: 8px; 
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 
  max-width: 300px; 
  z-index: 10;
}

.tip-icon { 
  font-size: 16px; 
}

.tip-text { 
  font-size: 14px; 
  color: #374151; 
  line-height: 1.4; 
}

.game-status-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  color: white;
  font-family: Arial, sans-serif;
}

.game-status-overlay.waiting {
  background-color: rgba(0, 0, 0, 0.7);
}

.game-status-overlay.playing {
  background-color: rgba(0, 0, 0, 0.7);
}

.game-status-overlay.finished {
  background-color: rgba(0, 0, 0, 0.7);
}

.status-content {
  text-align: center;
  padding: 20px;
  background-color: rgba(0, 0, 0, 0.8);
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

.status-content h3 {
  margin-bottom: 10px;
  color: #fff;
}

.status-content p {
  margin-bottom: 15px;
  color: #eee;
}

.player-ready-status {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.player-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background-color: #f0f0f0;
  border-radius: 5px;
}

.player-name {
  font-weight: bold;
  color: #333;
}

.ready-indicator {
  font-size: 14px;
  font-weight: bold;
}

.ready-indicator.ready {
  color: #4CAF50; /* 绿色 */
}

.ready-indicator.not-ready {
  color: #F44336; /* 红色 */
}

.current-player {
  margin-top: 15px;
  font-size: 18px;
  font-weight: bold;
  color: #fff;
}

.final-ranking {
  margin-top: 20px;
  text-align: left;
  padding-left: 20px;
}

.final-ranking h4 {
  margin-bottom: 10px;
  color: #fff;
}

.ranking-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  color: #eee;
}

.rank {
  font-weight: bold;
  margin-right: 15px;
  color: #FFD700; /* 金色 */
}

.player-name {
  flex-grow: 1;
  margin-right: 15px;
}

.score {
  font-weight: bold;
  color: #FFD700; /* 金色 */
}

.reset-btn {
  margin-top: 20px;
  padding: 10px 20px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  font-weight: bold;
  transition: background-color 0.3s ease;
}

.reset-btn:hover {
  background-color: #45a049;
}
</style> 